// Copyright 2011-2012, Vanya Davidenko.
// Используемая кодировка: UTF-8.

#ifndef LIBV_BOOST_AUTO_H_
#define LIBV_BOOST_AUTO_H_

#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/typeof/typeof.hpp>



// BOOST_AUTO генерирует неконстантное значение, игнорируя ссылки и const,
// что соответствует семантике ключевого слова auto в С++-11.
// Однако последнее позволяет еще и добавлять модификаторы типа (const, &).
// LIBV_AUTO_x позволяет исправить этот недостаток, явно указывая модификаторы.

// auto, неконстантное значение
#define LIBV_AUTO BOOST_AUTO

// const auto
#define LIBV_AUTO_CONST(Var, Expr)  \
    boost::add_const<               \
        BOOST_TYPEOF(Expr)          \
    >::type Var = (Expr)

// auto&
#define LIBV_AUTO_REF(Var, Expr)  \
    boost::add_reference<         \
        BOOST_TYPEOF(Expr)        \
    >::type Var = (Expr)

// const auto&
#define LIBV_AUTO_CREF(Var, Expr)  \
    boost::add_reference<          \
        boost::add_const<          \
            BOOST_TYPEOF(Expr)     \
        >::type                    \
    >::type Var = (Expr)



#define LIBV_AUTO_TPL BOOST_AUTO_TPL

#define LIBV_AUTO_CONST_TPL(Var, Expr)  \
    typename boost::add_const<          \
        BOOST_TYPEOF_TPL(Expr)          \
    >::type Var = (Expr)

#define LIBV_AUTO_REF_TPL(Var, Expr)  \
    typename boost::add_reference<    \
        BOOST_TYPEOF_TPL(Expr)        \
    >::type Var = (Expr)

#define LIBV_AUTO_CREF_TPL(Var, Expr)  \
    typename boost::add_reference<     \
        boost::add_const<              \
            BOOST_TYPEOF_TPL(Expr)     \
        >::type                        \
    >::type Var = (Expr)

#endif  // LIBV_BOOST_AUTO_H_
